package com.cloud.phone.utils

import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.app.ActivityManager.RunningAppProcessInfo
import android.app.usage.UsageStatsManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.NameNotFoundException
import android.net.Uri
import android.net.VpnService
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.text.TextUtils
import android.util.Log
import com.blankj.utilcode.util.LogUtils
import com.cloud.phone.MainActivity
import com.cloud.phone.base.BaseApp
import com.cloud.phone.bean.AppInfo
import com.cloud.phone.constants.Constants
import com.cloud.phone.service.CloudVpnService
import com.cloud.phone.task.TaskManager
import com.cloud.phone.task.bean.ProxyInfoBean
import com.cloud.phone.task.bean.StopVpnMsg
import com.cloud.phone.task.taskCongfig.FindIdResouresConfig
import com.cloud.phone.tools.AccessibilityTool
import com.cloud.phone.tools.AutoUtil
import com.cloud.phone.view.TsUtils
import org.greenrobot.eventbus.EventBus
import java.io.BufferedReader
import java.io.File
import java.io.IOException
import java.io.InputStreamReader


/**
 * @auth: njb
 * @date: 2024/4/17 15:10
 * @desc: 描述
 */
class AppUtils {
    companion object {
        private val TAG = "AppUtils"
        fun getRunningAppPackageName(context: Context): String? {
            val activityManager =
                context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
            // 获取正在运行的任务列表
            val runningTaskInfo = activityManager.getRunningTasks(1)[0]
            // 获取任务栈顶的Activity的包名
            return runningTaskInfo.topActivity?.packageName
        }

        fun startApp(context: Context, packageName: String, className: String) {
            val intent = Intent()
            intent.setComponent(ComponentName(packageName, className))
            // 启动应用程序
            context.startActivity(intent);
        }


        /**
         * 判断应用是否安装
         */
        fun isAppInstall(context: Context, packageName: String?): Boolean {
            val packageManager = context.packageManager
            val intent = packageManager.getLaunchIntentForPackage(packageName!!)
            if (intent != null) {
                return true
            } else {
                return false
            }
        }


        fun launchApp(context: Context, packageName: String?) {
            val packageManager = context.packageManager
            val intent = packageManager.getLaunchIntentForPackage(packageName!!)
            if (intent != null) {
                intent.addCategory(Intent.CATEGORY_LAUNCHER)
                context.startActivity(intent)
            } else {
                // 应用程序不存在，或者没有启动界面
//                TsUtils.showTips("应用程序未安装或无法启动")
            }
        }

        /**
         * 打开app
         */
        fun openApp(context: Context, packageName: String?) {
            val packageManager = context.packageManager
            val intent = packageManager.getLaunchIntentForPackage(packageName!!)
            if (intent != null) {
                intent.addCategory(Intent.CATEGORY_LAUNCHER)
                context.startActivity(intent)
                Constants.IS_APP_START = true
                Constants.TASK_STATUS = true
                Constants.TASK_IS_RUNNING = true
                LogUtils.d(TAG, "app已打开")
            } else {
                // 应用程序不存在，或者没有启动界面
//                TsUtils.showTips("应用程序未安装或无法启动")
                LogUtils.d(TAG, "应用程序未安装或无法启动")
                Constants.IS_APP_START = false
                Constants.TASK_STATUS = false
                Constants.TASK_IS_RUNNING = false
            }
        }

        fun getApkName(context: Context): String {
            var apkName = ""
            try {
                val applicationInfo =
                    context.packageManager.getApplicationInfo(context.packageName, 0);
                apkName = context.packageManager.getApplicationLabel(applicationInfo).toString();
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return apkName
        }

        fun killAppByPackageName(context: Context, packageName: String) {
            val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
            am.killBackgroundProcesses(packageName)
        }

        /**
         * 获取手机已安装应用列表
         * @param context
         * @return
         */
        @SuppressLint("QueryPermissionsNeeded")
        fun getAllApps(context: Context): List<AppInfo> {
            val packageManager = context.packageManager
            val appsInfo = mutableListOf<AppInfo>()
            val packages = packageManager.getInstalledPackages(0)
            try {
                // if()里的值如果<=0则为自己装的程序，否则为系统工程自带
                for (packageInfo in packages) {
                    if (!isSystemApplication(context, packageInfo.packageName)) {
                        packageInfo.applicationInfo?.let {
                            val appName = it.loadLabel(packageManager).toString()
                            val packageName = packageInfo.packageName
                            val versionName = packageInfo.versionName
                            val versionCode = packageInfo.versionCode
                            val appIcon = it.loadIcon(packageManager)
                            appsInfo.add(
                                AppInfo(appName, packageName, versionCode, versionName.toString(), "", appIcon)
                            )
                        }

                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return appsInfo
        }

        fun isSystemApplication(context: Context, packageName: String?): Boolean {
            val mPackageManager = context.packageManager
            try {
                val packageInfo =
                    mPackageManager.getPackageInfo(packageName!!, PackageManager.GET_CONFIGURATIONS)
                if (packageInfo.applicationInfo!!.flags and ApplicationInfo.FLAG_SYSTEM != 0) {
                    return true
                }
            } catch (e: NameNotFoundException) {
                e.printStackTrace()
            }
            return false
        }

        /**
         * 获取APP的启动类
         * @param context
         * @param packageName
         * @return
         */
        fun getAppStartClass(context: Context, packageName: String?): String {
            val packageManager = context.packageManager
            try {
                val intent = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
                val list =
                    packageManager.queryIntentActivities(intent, PackageManager.GET_ACTIVITIES)
                var i = 0
                val count = list.size
                while (i < count) {
                    if (TextUtils.equals(list[i].activityInfo.packageName, packageName)) {
                        return list[i].activityInfo.name
                    }
                    i++
                }
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
            } finally {
                return ""
            }
        }

        /**
         * 执行adb命令
         * @param command
         */
        fun executeAdbCommand(command: String) {
            try {
                val process = Runtime.getRuntime().exec("adb shell $command")
                val reader = BufferedReader(InputStreamReader(process.inputStream))
                var line: String?
                while (reader.readLine().also { line = it } != null) {
                    println(line)
                }
                process.waitFor()
                reader.close()
            } catch (e: IOException) {
                e.printStackTrace()
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
        }

        //自动开启无障碍服务
        fun autoOpenAccessibilityService(context: Context) {
            Settings.Secure.putString(
                context.contentResolver,
                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
                "com.cloud.phone/.service.AccessibilityAutoMainService"
            )
            Settings.Secure.putString(
                context.contentResolver,
                Settings.Secure.ACCESSIBILITY_ENABLED, "1"
            )
        }

        //自动关闭无障碍服务
        private fun autoCloseAccessibilityService(context: Context) {
            Settings.Secure.putString(
                context.contentResolver,
                Settings.Secure.ACCESSIBILITY_ENABLED,
                "com.cloud.phone/.service.AccessibilityAutoMainService"
            )
            Settings.Secure.putString(
                context.contentResolver,
                Settings.Secure.ACCESSIBILITY_ENABLED, "0"
            )
        }


        fun getRunningProcesses(context: Context): AppInfo {
            val appInfo = AppInfo()
            try {
                val m = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
                val now = System.currentTimeMillis()
                //获取60秒之内的应用数据
                val stats = m.queryUsageStats(UsageStatsManager.INTERVAL_BEST, now - 60 * 1000, now)
                Log.i(TAG, "Running app number in last 60 seconds : " + stats!!.size)
                var topActivity = ""
                //取得最近运行的一个app，即当前运行的app
                if (stats.isNotEmpty()) {
                    var j = 0
                    for (i in stats.indices) {
                        if (stats[i].lastTimeUsed > stats[j].lastTimeUsed) {
                            j = i
                        }
                        topActivity = stats[j].packageName
                        appInfo.apkName = topActivity
                        Log.i(TAG, "top running app is : $topActivity")
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return appInfo
        }

        /**
         * 检查是否有VPN授权弹框出现并允许VPN权限开启
         * @throws InterruptedException
         */
        @Throws(InterruptedException::class)
        fun checkAndClickVpnConfirmBt() {
            if (!AccessibilityUtil.isStartAccessibilityServiceEnable(BaseApp.app.baseContext)) {
                LogUtils.i("未开启无障碍服务，无法进行关闭")
                return
            }
            var service = TaskManager.getInstance().accessibilityService
            if (service == null) {
                LogUtils.i("未开启无障碍服务，无法进行关闭")
                return
            }
            Thread.sleep(3000)
            if (FindIdResouresConfig.vpnAndroidPkgName == AccessibilityTool.getInstance()
                    .getCurrentPagePackageName(service)
            ) {
                val isVpnDialogClickSuccess = AutoUtil.getInstance()
                    .findNodeByIdAndClick(FindIdResouresConfig.vpnPermissionAllowBtId)
                if (isVpnDialogClickSuccess) {
                    showLogAndTsPrint("已允许VPN权限")
                } else {
                    showLogAndTsPrint("未能成功允许VPN权限")
                }
            }
        }

        private fun showLogAndTsPrint(msg: String?) {
            LogUtils.v(msg)
            if (Looper.myLooper() != Looper.getMainLooper()) {
                Handler(Looper.getMainLooper()).post { TsUtils.showTips(msg) }
            } else {
                TsUtils.showTips(msg)
            }
        }

        fun prepareVpn(activity: MainActivity) {
            try {
                VpnService.prepare(activity)?.let {
                    activity.vpnContent.launch(it)
                    TsUtils.showTips("权限申请：开始")
                    checkAndClickVpnConfirmBt()
                }.run {
                    TsUtils.showTips("权限申请：完成开启VPN")
                    startVpn(activity)
                    TsUtils.showTips("VPN开启完成")
                }
            } catch (e: Exception) {
                e.printStackTrace()
                TsUtils.showTips("错误2222："+e.cause+e.message)
            }
        }

        fun startVpn(activity: MainActivity) {
            try {
                activity.apply {
                    this.startService(Intent(this, CloudVpnService::class.java).also {
                        it.action = Constants.ACTION_CONNECT
                    })
                }
            } catch (e: Exception) {
                e.printStackTrace()
                TsUtils.showTips("开启VPN失败："+e.cause+","+e.message)
            }
        }

        fun stopVpn(activity: MainActivity) {
            try {
                activity.apply {
                    this.startService(Intent(this, CloudVpnService::class.java).also {
                        it.action = Constants.ACTION_DISCONNECT
                    })
                }
                Constants.TASK_STATUS = true
                Constants.TASK_IS_RUNNING = true
                TsUtils.showTips("vpn已停止")
            } catch (e: Exception) {
                e.printStackTrace()
                EventBus.getDefault().post(StopVpnMsg())
            }
/*            Engine.stop()
            Constants.TASK_STATUS = true
            Constants.TASK_IS_RUNNING = true
            Constants.IS_MY_VPN_SERVICE_RUNNING = false
            CloudVpnService.parcelFileDescriptor = null*/
        }


        fun getRunningAllApps(context: Context): List<String> {
            val packageNames: MutableList<String> = ArrayList()
            try {
                val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
                val processInfoList = manager.runningAppProcesses
                for (processInfo in processInfoList) {
                    packageNames.add(processInfo.pkgList[0])
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return packageNames
        }

        fun smartInstall(file: File,activity: Activity) {
            if (!file.exists()) {
                return
            }
            val intent = Intent(Intent.ACTION_VIEW)
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            //版本在7.0以上是不能直接通过uri访问的
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                val apkUri: Uri = AccessibilityUtil.getUriForFile(activity, file)
                //添加这一句表示对目标应用临时授权该Uri所代表的文件
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
            } else {
                intent.setDataAndType(
                    Uri.fromFile(file),
                    "application/vnd.android.package-archive"
                )
            }
            activity.startActivity(intent)
        }

        /**
         * 获取版本号
         *
         * @return 当前应用的版本号
         */
        fun getPackageVersionName(context: Context, pkgName: String): String? {
            return try {
                val manager = context.packageManager
                val info = manager.getPackageInfo(pkgName, 0) //PackageManager.GET_CONFIGURATIONS
                info.versionName
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
                null
            }
        }


        fun getPackageVersionCode(context: Context, pkgName: String): Int {
            return try {
                val manager = context.packageManager
                val info = manager.getPackageInfo(pkgName, 0)
                info.versionCode
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
                -1
            }
        }

        //判断版本是否更新
       fun checkVersion(proxyInfo: ProxyInfoBean,context: Context): Boolean {
            return proxyInfo.version > getPackageVersionCode(context, context.packageName)
        }
    }
}